/*
 * @version: 1.0
 * @Author: zhl
 * @Date: 2021-12-08 13:32:16
 * @LastEditors: zhl
 * @LastEditTime: 2022-02-08 13:30:11
 * @Description: 
 */
#include "SerialPacketManager.h"
#include "json.hpp"
#include "common.h"
#include "Base64.hpp"


using json = nlohmann::json;


void to_json(json& j, const SERIAL_RESPONSE_MESSAGE& p) {
    j = json{
        {"token",p.token}, 
        {"status", p.status}, 
        {"prm", p.prm}, 
        {"port", p.port}, 
        {"data", p.data}, 
        {"timestamp", p.timestamp}
        };
}

void from_json(const json& j, SERIAL_RESPONSE_MESSAGE& p) {
    j.at("token").get_to(p.token);
    j.at("status").get_to(p.status);
    j.at("prm").get_to(p.prm);
    j.at("port").get_to(p.port);
    j.at("data").get_to(p.data);
    j.at("timestamp").get_to(p.timestamp);
}

void to_json(json& j, const SERIAL_REQUEST_MESSAGE& p) {
    j = json{
        {"token", p.token}, 
        {"prio", p.prio}, 
        {"prm", p.prm}, 
        {"taskTimeout", p.taskTimeout}, 
        {"byteTimeout", p.byteTimeout}, 
        {"frameTimeout", p.frameTimeout}, 
        {"port", p.port}, 
        {"estSize", p.estSize}, 
        {"param", {
            {"baudRate", p.param.baudRate}, 
            {"byteSize", p.param.byteSize}, 
            {"parity", p.param.parity}, 
            {"stopBits", p.param.stopBits}}
        }, 
        {"data", p.data}, 
        {"timestamp", p.timestamp}};
}

void from_json(const json& j, SERIAL_REQUEST_MESSAGE& p) {
    j.at("token").get_to(p.token);
    j.at("prio").get_to(p.prio);
    j.at("prm").get_to(p.prm);
    j.at("taskTimeout").get_to(p.taskTimeout);
    j.at("byteTimeout").get_to(p.byteTimeout);
    j.at("frameTimeout").get_to(p.frameTimeout);
    j.at("param").at("baudRate").get_to(p.param.baudRate);
    j.at("param").at("byteSize").get_to(p.param.byteSize);
    j.at("param").at("parity").get_to(p.param.parity);
    j.at("param").at("stopBits").get_to(p.param.stopBits);
    j.at("port").get_to(p.port);
    j.at("estSize").get_to(p.estSize);
    j.at("data").get_to(p.data);
    j.at("timestamp").get_to(p.timestamp);
}


SerialPacketManager::SerialPacketManager(/* args */){
    c_token = 0;
}

SerialPacketManager::~SerialPacketManager(){
}

int SerialPacketManager::get_serial_request_msg(std::string port, int req_id, SERIAL_PARAMS params, char *sendBuf, int buf_len, std::string &msg, uint32_t timeout){
    int tl = get_base64_len(buf_len) + 100;
    char targetBuf[tl] = {0};
    // hex_to_str((unsigned char *)sendBuf, buf_len, (char *)targetBuf, &tl);
    tl = base64_encode(sendBuf, buf_len, targetBuf, tl);
    SERIAL_REQUEST_MESSAGE srmsg;
    srmsg.token = req_id;
    srmsg.prio = 9;
    srmsg.prm = 1;
    srmsg.taskTimeout = timeout;
    srmsg.byteTimeout = 100;
    srmsg.frameTimeout = timeout;
    srmsg.param.baudRate = params.baudRate;
    srmsg.param.byteSize = params.byteSize;
    srmsg.param.parity = params.parity;
    srmsg.param.stopBits = params.stopBits;
    srmsg.port = port;        
    srmsg.data = targetBuf;
    srmsg.estSize = srmsg.data.length();
    get_uart_timestamp(srmsg.timestamp);

    json j = srmsg;
    msg = j.dump();
    return msg.length();
}

int SerialPacketManager::get_serial_response_msg(std::string &msg, char *recvBuf, int &recvBuf_len){
    if((NULL == recvBuf) || (1 > recvBuf_len) || (msg.empty())){
        recvBuf_len = -1;
        return -1;
    }
    auto j = json::parse(msg);

    if(nullptr == j["token"]){
        c_token = 0;
        CLogger::getInstance()->log_d("get_serial_response_msg token isn't exists.");
    }else {
        if(j["token"].is_number()){
            c_token = j["token"].get<int>();
        }
    }

    if(nullptr == j["data"]){
        recvBuf_len = -1;
        CLogger::getInstance()->log_d("get_serial_response_msg no data.");
        return -1;
    }
    std::string data = j["data"].get<std::string>();
    if((data.empty()) || (recvBuf_len < (int)(data.length()/2 + 1))){
        recvBuf_len = -1;
        return -1;
    }
    int ret = base64_decode((char *)data.c_str(), data.length(), recvBuf, recvBuf_len);
    if(1 > ret){
        recvBuf_len = -1;
         CLogger::getInstance()->log_d("get_serial_response_msg decode error.");
        return -1;
    }
    recvBuf_len = ret;
    return ret;
}